import OpenGL
import OpenGL.GL
import OpenGL.GLU
import OpenGL.GLUT
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import math
from math import *

looping=True


class Monster:
    x=y=z=.6
    yaw=0.0
    pitch=0.0

PLAYER_SPEED=0.3
player=Monster()

def kbd(k,b,c):
    global looping
    if k=='q':
        looping=False
    if k=='w':
        player.x+=cos(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        player.y+=sin(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        player.z+=sin(player.pitch)*PLAYER_SPEED

    if k=='s':
        player.x-=cos(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        player.y-=sin(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        player.z-=sin(player.pitch)*PLAYER_SPEED
        
    if k=='a':
        player.x-=sin(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        player.y+=cos(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        
    if k=='d':
        player.x+=sin(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        player.y-=cos(player.yaw)*cos(player.pitch)*PLAYER_SPEED
        


prevx=0
prevy=0
def mouse(x,y):
    global prevx,prevy
    dx=prevx-x
    dy=prevy-y
    player.yaw+=dx*0.01
    player.pitch+=dy*0.01
    if player.pitch>1.57: player.pitch=1.57
    if player.pitch<-1.57: player.pitch=-1.57
    prevx=x
    prevy=y
    pass

def drawAxes():
    glBegin(GL_LINES)
    glColor3f(1,0,0)
    glVertex3f(0,0,0)
    glVertex3f(1,0,0)
    glColor3f(0,1,0)
    glVertex3f(0,0,0)
    glVertex3f(0,1,0)
    glColor3f(0,0,1)
    glVertex3f(0,0,0)
    glVertex3f(0,0,1)
    glEnd()

def setupLight():
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    glLightfv(GL_LIGHT0,GL_DIFFUSE,(1,1,1,1))
    glLightfv(GL_LIGHT0,GL_AMBIENT,(0,.2,.5,1))
    glLightfv(GL_LIGHT0,GL_POSITION,(10,10,10,1))

def drawSurface():
    dx=1.0
    dy=1.0
    def F(x,y):
        return sin(0.3*x)+sin(0.7*y)*sin(0.5*y)
    def CF(x,y):
        return (2+F(x,y))*0.25
    glBegin(GL_QUADS)
    glColor3f(.4,.8,.3)
    for a in xrange(20):
        for b in xrange(20):
            aa=a+1
            bb=b+1
            x=a*dx
            y=b*dy

            xx=aa*dx
            yy=bb*dy

            glColor3f(.4,CF(x,y),.3)
            glVertex3f(x,y,F(x,y))
            
            glColor3f(.4,CF(xx,y),.3)
            glVertex3f(xx,y,F(xx,y))

            glColor3f(.4,CF(xx,yy),.3)
            glVertex3f(xx,yy,F(xx,yy))

            glColor3f(.4,CF(x,yy),.3)
            glVertex3f(x,yy,F(x,yy))
            
    glEnd()

def display():
    glClearColor(.4,.5,.6,1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(90,1,0.1,100.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    gluLookAt(player.x,player.y,player.z,
              player.x+cos(player.yaw)*cos(player.pitch),
              player.y+sin(player.yaw)*cos(player.pitch),
              player.z+sin(player.pitch),
              0,0,1)
    glEnable(GL_DEPTH_TEST)
    setupLight()
    drawAxes()
    drawSurface()
    glutSwapBuffers()

def idle():
    display()

def main():
    glutInit()
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH)
    glutCreateWindow('qwe')
    glutDisplayFunc(display)
    glutKeyboardFunc(kbd)
    glutPassiveMotionFunc(mouse)
    while(looping):
        glutMainLoopEvent()
        glutPostRedisplay()
    pass


main()
